home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / filesys / mfs609s.zoo / minit.c < prev    next >
C/C++ Source or Header  |  1993-11-25  |  15KB  |  633 lines

  1. /* minit Minix INITializer . Freely distributable Minix filesys creator.
  2.  * Copyright S N Henson 1991,1992,1993.
  3.  * Use entirely at your own risk ! If it trashes your hard-drive then
  4.  * it isn't my fault ! 
  5.  */
  6.  
  7. /* Version 0.26 */
  8.  
  9.  
  10. #include <mintbind.h>
  11. #include <stdio.h>
  12. #include <time.h>
  13. #include <string.h>
  14. #include <unistd.h>
  15. #include <stdlib.h>
  16. #include <alloc.h>
  17.  
  18. #include "minixfs/hdio.h"
  19. #include "minixfs/xhdi.h"
  20. #include "minixfs/pun.h"
  21.  
  22. #define MNAME_MAX 14
  23.  
  24. int shift,drive=-1;
  25. long numblocks,numinodes,incr=1;
  26.  
  27. /* various flags */
  28. char protect,sonly,v2,lrecno,tst;
  29.  
  30. struct hdinfo hdinf;
  31.  
  32. unsigned char block_buf[1024];
  33.  
  34. /* Structures we will need */
  35.  
  36. typedef struct  {
  37.   unsigned short  s_ninodes;    /* # usable inodes on the minor device */
  38.   unsigned short  s_nzones;    /* total device size, including bit maps etc */
  39.   unsigned short s_imap_blks;    /* # of blocks used by inode bit map */
  40.   unsigned short s_zmap_blks;    /* # of blocks used by zone bit map */
  41.   unsigned short s_firstdatazn;    /* number of first data zone */
  42.   short int s_log_zsize;    /* log2 of blocks/zone */
  43.   unsigned long s_max_size;    /* maximum file size on this device */
  44.   short s_magic;        /* magic number to recognize super-blocks */
  45.   short pad;            /* padding */
  46.   long s_zones;            /* equivalent to 's_nzones' for V2 */
  47. } super_block;
  48.  
  49.  
  50.  
  51. typedef struct {        /* directory entry */
  52.   unsigned short d_inum;    /* inode number */
  53.   char d_name[MNAME_MAX];        /* character string */
  54. } dir_struct;
  55.  
  56. typedef struct {        /* disk inode. */
  57.   unsigned short i_mode;        /* file type, protection, etc. */
  58.   unsigned short i_uid;            /* user id of the file's owner */
  59.   unsigned long  i_size;        /* current file size in bytes */
  60.   unsigned long  i_mtime;        /* when was file data last changed */
  61.   unsigned char i_gid;            /* group number */
  62.   unsigned char i_nlinks;        /* how many links to this file */
  63.   unsigned short i_zone[9];    /* block nums for direct, ind, and dbl ind */
  64. } d_inode;
  65.  
  66. typedef struct {
  67. unsigned short i_mode;
  68. unsigned short i_nlinks;
  69. unsigned short i_uid;
  70. unsigned short i_gid;
  71. unsigned long i_size;
  72. unsigned long i_atime;
  73. unsigned long i_mtime;
  74. unsigned long i_ctime;
  75. long i_zone[10];
  76. } d_inode2;
  77.  
  78. /* prototypes */
  79.  
  80. #ifdef __STDC__
  81. # define    P(s) s
  82. #else
  83. # define P(s) ()
  84. #endif
  85.  
  86.  
  87. void main P((int argc , char **argv ));
  88. int nrwabs P((int rw , void *buf , unsigned count , long recno , int drive ));
  89. void get_block P((long num ));
  90. void put_block P((long num ));
  91. void check_lrecno P((void ));
  92. void warn P((void ));
  93.  
  94. #undef P
  95.  
  96. void main(argc,argv)
  97. int argc;
  98. char **argv;
  99. {
  100.     extern int optind,opterr;
  101.     extern char *optarg;
  102.     extern int __mint;
  103.     long hderr;
  104.     int c ;
  105.     static char err=0;
  106.     int i,j;
  107.     _BPB *bpb;
  108.     unsigned short ioff,zone1;
  109.         super_block *sblk=(super_block *)block_buf,csblk;
  110.         d_inode *rip=(d_inode *)block_buf;
  111.     d_inode2 *ripn=(d_inode2 *)block_buf;
  112.         dir_struct *dir=(dir_struct *)block_buf;
  113.     unsigned short *srt=(unsigned short *)block_buf;
  114.     long icount, zcount;
  115.  
  116.     struct
  117.     {
  118.         long start;
  119.         long finish;
  120.         char shadow;
  121.         char scsiz;
  122.     } pp;
  123.  
  124.     if(__mint==0)
  125.     {
  126.         fprintf(stderr,"Error: MiNT not active.\n");
  127.         exit(1);
  128.     }
  129.  
  130.     /* Parse command-line options */
  131.     opterr=0;
  132.     while((c=getopt(argc,argv,"b:B:i:I:n:pPSZztV"))!=EOF)
  133.     {
  134.             switch(c){
  135.  
  136.                 case 'B':
  137.             case 'b':
  138.             numblocks=atol(optarg);
  139.             break;
  140.  
  141.             case 'n':
  142.             incr=atol(optarg);
  143.             break;
  144.  
  145.             case 'i':
  146.             case 'I':
  147.             numinodes=atol(optarg);
  148.             break;
  149.  
  150.             case 'P':
  151.             protect=1;
  152.             break;
  153.  
  154.             case 'p':
  155.             protect=2;
  156.             break;
  157.  
  158.             case 'S':
  159.             sonly=1;
  160.             break;
  161.  
  162.             case 'Z':
  163.             protect=1;
  164.             break;    
  165.  
  166.             case 'z':
  167.             protect=2;
  168.             break;
  169.  
  170.             case 'V':
  171.             v2=1;
  172.             break;
  173.  
  174.             case 't':
  175.             tst=1;
  176.             break;
  177.  
  178.             case '?':
  179.             err=1;
  180.             break;
  181.         }
  182.     }
  183.  
  184.     if(argc-optind!=1 || err)
  185.     {
  186.         fprintf(stderr,"Minix-compatible filesystem initializer\n");
  187.         fprintf(stderr,"Copyright S N Henson 1991,1992,1993\n");
  188.         fprintf(stderr,"Version 0.26\n"); 
  189.         fprintf(stderr,"Usage\t(auto)\t: minit drive\n");
  190.         fprintf(stderr,"\t(manual): minit -b blocks -i inodes drive\n");
  191.         fprintf(stderr,"Also :\t-S only write out super-block\n");
  192.         fprintf(stderr,"\t-P/-Z protect filesystem with null disk\n");
  193.         fprintf(stderr,"\t-p/-z make null disk of existing filestystem\n");
  194.         fprintf(stderr,"\t-V make a V2 filesystem\n");
  195.         fprintf(stderr,"\t-n dirincrement\n");
  196.         fprintf(stderr,"\t-t test mode (no writing)\n");
  197.         exit(1);
  198.     }
  199.     drive=(argv[optind][0] & ~32)-'A' ;
  200.  
  201.     bpb=Getbpb(drive);
  202.  
  203.     /* Sanity checking time */
  204.  
  205.     if((incr < 1) || (incr > 16) || ( (incr) & (incr-1) ) )
  206.     {
  207.         fprintf(stderr,"Dirincrement must be a power of two between\n");
  208.         fprintf(stderr,"1 and 16 (inclusive)\n");
  209.         exit(1);
  210.     }
  211.  
  212.     if( (numinodes < 0) || (numinodes > 65535) )
  213.     {
  214.         fprintf(stderr,"Need at least 1 and no more than 65535 inodes\n");
  215.         exit(1);
  216.     }
  217.  
  218.     if(protect==2 && bpb->recsiz!=512)
  219.     {
  220.         fprintf(stderr,"Sorry can't add protection to this filesytem.\n");
  221.         fprintf(stderr,"Sector size not 512 bytes.\n");
  222.         exit(1);
  223.     }
  224.  
  225.     /* Test for physical partition */
  226.     if(!Dcntl(0x109,argv[optind],&pp) && pp.start!=-1) 
  227.     {
  228.         long tstack;
  229.         hdinf.start=pp.start;
  230.         hdinf.size=pp.finish-hdinf.start+1;
  231.         hdinf.scsiz=pp.scsiz;
  232.         hdinf.major = pp.shadow;
  233.         hdinf.drive = drive;
  234.         tstack=Super(0l);
  235.         if(init_icd()==2)
  236.         {
  237.             Super(tstack);
  238.             fprintf(stderr,"Can't kludge ICD bug\n");
  239.             exit(1);
  240.         }
  241.         Super(tstack);
  242.         hdinf.rwmode = RW_PHYS;
  243.         if(hdinf.start > 0xfffe)
  244.         {
  245.             if(no_plrecno(hdinf.major))
  246.             fprintf(stderr,"Cannot access Drive %c:\n",drive+'A');
  247.             hdinf.rwmode |= RW_LRECNO;
  248.         }
  249.     }
  250.     else 
  251.     {
  252.         pp.start=-1;
  253.         if( (hderr=get_hddinf(drive,&hdinf,0)) )
  254.         {
  255.             fprintf(stderr,"Cannot access Drive %c: %s\n",drive+'A',
  256.                                 hdd_err[hderr]);
  257.             exit(1);
  258.         }
  259.     }
  260.     if(tst)
  261.     {
  262.         struct hdinfo hdinf2;
  263.         unsigned int llrecno,xhret,no_phys;
  264.         no_phys=0;
  265.         if(pp.start==-1)
  266.         {
  267.             llrecno=no_lrecno(drive);
  268.             if(llrecno && llrecno!=3)
  269.                 fprintf(stderr,"Logical lrecno error\n");
  270.             else fprintf(stderr,"Logical lrecno OK\n");
  271.         }
  272.         else
  273.         {
  274.             fprintf(stderr,"Physical Partition\n");
  275.             hdinf2=hdinf;
  276.         }
  277.         if( (no_phys=get_hddinf(drive,&hdinf2,1) ) )
  278.     fprintf(stderr,"Can't get physical drive info: %s\n",hdd_err[no_phys]);
  279.         else if( (hdinf2.rwmode & RW_MODE) != RW_XHDI )
  280.         {
  281.             llrecno=no_plrecno(hdinf2.major);
  282.             if(llrecno && llrecno!=3)
  283.                 fprintf(stderr,"Physical lrecno error\n");
  284.             else fprintf(stderr,"Physical lrecno OK\n");
  285.         }
  286.         if( (xhret=XHGetVersion()) ) fprintf(stderr,"XHDI supported"
  287.                    " version %x.%02x\n", xhret>>8,xhret & 0xff);
  288.  
  289.         else fprintf(stderr,"XHDI not supported\n");
  290.         if(!no_phys)
  291.         {
  292.           fprintf(stderr,"Partition start: %ld\n",hdinf2.start);
  293.           if(hdinf2.size)
  294.             fprintf(stderr,"Partition size: %ld\n",hdinf2.size);
  295.           if( (hdinf2.rwmode & RW_MODE) == RW_PHYS)
  296.           {
  297.             unsigned ddev;
  298.             char *sbus;
  299.             ddev=hdinf2.minor;
  300.             fprintf(stderr,"Unit number %d\n",ddev);
  301.             if( ddev & PUN_IDE) sbus="IDE";
  302.             else
  303.             {
  304.                 if( ddev & PUN_SCSI) sbus="SCSI";
  305.                 else sbus="ACSI";
  306.             }
  307.             fprintf(stderr,"%s bus: device %d.(",sbus,
  308.                                    ddev & PUN_UNIT);
  309.             if(ddev & PUN_REMOVABLE) fprintf(stderr,"Removable)\n");
  310.             else fprintf(stderr,"Non-removable)\n");
  311.           }
  312.           else fprintf(stderr,"Major number %d Minor number %d\n",
  313.                              hdinf2.major,hdinf2.minor);
  314.         }
  315.  
  316.     }
  317.  
  318.     if(!numblocks) numblocks=hdinf.size>>hdinf.scsiz;
  319.     else if(hdinf.size && (numblocks > hdinf.size>>hdinf.scsiz))
  320.     {
  321.         fprintf(stderr,"Partition has only %ld blocks\n",
  322.                                hdinf.size>>hdinf.scsiz);
  323.         exit(1);
  324.     }
  325.  
  326.     /* read in boot sector */
  327.     get_block(0);
  328.  
  329.     /* If size of partition not known try BPB/boot sector */
  330.     if(!numblocks)
  331.     {
  332.         if(!bpb || (bpb->recsiz & 511))
  333.         {
  334.             fprintf(stderr,"Can't figure out partition size: "
  335.                              "try the -b option\n");
  336.             exit(1);
  337.         }
  338.  
  339.         numblocks=( (block_buf[19]+( ((long)block_buf[20])<<8))*
  340.                                    bpb->recsiz)>>10;
  341.         if(numbloc